Programmierung von CAx-Systemen

David Straub

CAx-Programmierung – D. Straub

Gliederung

  1. Einführung
  2. Topologie
  3. Grundformen
  4. Kurven
  5. Freiformgeometrie
  6. Profile
  7. Codequalität
  8. Datenaustausch
  9. Robustheit
  10. Simulation
  11. Optimierung
CAx-Programmierung – D. Straub

Darstellung von Geometrie in CAD-Systemen

Dreidimensionale Geometrie kann in CAD-Systemen auf verschiedene Arten dargestellt werden:

  • CSG (Constructive Solid Geometry): Volumen durch boolesche Operationen einfacher Körper
  • B-Rep (Boundary Representation): Oberfläche definiert Volumen, Kanten definieren Flächen
  • Mesh (Netz): Form aus vielen kleinen Facetten angenähert – Dreiecke auf der Oberfläche oder Tetraeder im Volumen

CAx-Programmierung – D. Straub

CSG (Constructive Solid Geometry)

Konstruktive Festkörpergeometrie

  • Modellierung durch boolesche Operationen (Union, Intersection, Difference)
  • Grundkörper: Würfel, Zylinder, Kugel, Kegel
  • Kompakt und intuitiv – die Darstellung hinter OpenSCAD (2010), das code-basiertes CAD populär machte
  • Grenze: Freiformflächen, Verrundungen, gezielte Flächenauswahl brauchen mehr
CAx-Programmierung – D. Straub

B-Rep (Boundary Representation)

Begrenzungsflächenmodell

  • Geometrie durch Oberfläche beschrieben
  • Hierarchie: Faces (Flächen), Edges (Kanten), Vertices (Ecken)
  • Standard in professionellen CAD-Systemen – das verwenden wir
  • Boolesche Operationen (+, -) nutzen wir weiter – ihr Ergebnis ist ein B-Rep mit auswählbaren Flächen und Kanten
CAx-Programmierung – D. Straub

Mesh (Netz)

Die Geometrie wird durch viele kleine Facetten angenähert – in zwei Arten:

  • Oberflächennetz: Dreiecke/Vierecke auf der Haut → 3D-Druck (STL), Visualisierung
  • Volumennetz: Tetraeder/Hexaeder füllen den Körper → FEM

Beide sind approximativ – die exakte Krümmung geht verloren.

Ein STL-Netz muss nur dicht sein und gut aussehen. Beim FEM-Netz bestimmen Größe und Form der Elemente die Genauigkeit der Rechnung – dazu mehr in Einheit 10.

CAx-Programmierung – D. Straub

Theorie A: Geometrie vs. Topologie, Grundelemente

CAx-Programmierung – D. Straub

Was ist der Unterschied?

Topologie beschreibt die Struktur eines Körpers:

  • Wie viele Flächen, Kanten, Ecken hat er? Wie sind diese verbunden?

Geometrie beschreibt die Form im Raum:

  • Wo liegen die Punkte? Welche Kurve/Fläche liegt zugrunde? Krümmung, Länge, Flächeninhalt

B-Rep = Topologie + Geometrie: Die Topologie liefert das Gerüst, die Geometrie füllt es mit konkreter Form.

CAx-Programmierung – D. Straub

Beispiel: Würfel vs. Quader

Beide haben dieselbe Topologie: 8 Ecken, 12 Kanten, 6 Flächen, jede Fläche von 4 Kanten begrenzt.

Aber unterschiedliche Geometrie: Würfel – alle Flächen quadratisch, alle Kanten gleich lang; Quader – Rechteckflächen, unterschiedliche Kantenlängen.

→ Gleiche Topologie, verschiedene Geometrie ist möglich!

CAx-Programmierung – D. Straub

Analogie: S-Bahn-Netz

Netzplan (Topologie): Welche Stationen sind verbunden? Wo muss ich umsteigen?

Geografische Karte (Geometrie): Wo liegen die Stationen genau? Wie lang ist die Strecke in km?

→ In CAD: B-Rep trennt genauso Struktur (Topologie) von Form (Geometrie).

CAx-Programmierung – D. Straub

Zur Erinnerung: unsere Grundplatte

from cadquery import func as cf

platte = cf.box(170, 110, 6)
grundplatte = cf.fillet(platte, platte.edges("|Z"), 6)

Letzte Woche gebaut, aber nicht angeschaut: was für ein Objekt ist das eigentlich, strukturell?

CAx-Programmierung – D. Straub

Topologie inspizieren

print("Faces:   ", len(grundplatte.Faces()))
print("Edges:   ", len(grundplatte.Edges()))
print("Vertices:", len(grundplatte.Vertices()))

Ergebnis: Faces: 10 Edges: 24 Vertices: 16 – ein Quader hätte 6/12/8. Warum mehr? Jede Verrundung ersetzt eine gerade Kante durch eine gekrümmte Fläche mit eigenen neuen Kanten und Ecken.

CAx-Programmierung – D. Straub

Zylinder: 3 Flächen, 3 Kanten, 2 Ecken

Ein glatter Zylinder, ganz ohne Verrundung:

zyl = cf.cylinder(d=20, h=20)
print(len(zyl.Faces()), len(zyl.Edges()), len(zyl.Vertices()))
# 3 3 2

Drei Flächen (Mantel, Boden, Deckel) sind klar. Aber 2 Ecken und 3 Kanten bei zwei runden Rändern – wie kommt das zustande?

CAx-Programmierung – D. Straub

Die Nahtkante

Die Mantelfläche ist ein aufgerolltes Rechteck. Wo seine Enden zusammenstoßen, liegt eine Nahtkante, die dieselbe Fläche zweimal begrenzt.

  • Ihre beiden Endpunkte sind die 2 Ecken
  • Zwei Kreisränder plus die Naht ergeben die 3 Kanten

Topologie zählt nach der tatsächlichen Verbindung der Elemente.

CAx-Programmierung – D. Straub

Die Nahtkante im Code

def show_topology(shape, indent=""):
    print(indent + shape.ShapeType())
    for child in shape:
        show_topology(child, indent + "  ")

show_topology(zyl)

In der Ausgabe enthält der Wire der Mantelfläche vier Edges: Kreis, Naht, Kreis, Naht. Die Nahtkante taucht zweimal auf – einmal für jede Seite des abgerollten Rechtecks.

CAx-Programmierung – D. Straub

Vertex – der Punkt

  • Nulldimensional – ein Punkt im Raum, Geometrie (x, y, z)
  • Begrenzungselement von Kanten
quader = cf.box(30, 20, 10)
v = quader.Vertices()[0]
print(v.toTuple())          # Position einer Ecke
CAx-Programmierung – D. Straub

Edge – die Kante

  • Eindimensional – ein Kurvenstück, begrenzt durch Vertices
  • Geometrie: eine parametrische Kurve (Linie, Kreis, Spline, …)
for k in quader.Edges():
    print(k.geomType(), round(k.Length(), 1))   # beim Quader: alle LINE
CAx-Programmierung – D. Straub

Wire – der Kantenzug

  • Geordnete, zusammenhängende Folge von Edges
  • Bildet die Kontur einer Fläche – selbst kein geometrisches Objekt
wire = quader.Faces()[0].Wires()[0]
print(len(wire.Edges()), "Kanten im Wire")   # 4

→ Eine Fläche kann mehrere Wires haben: äußere Kontur + innere Löcher

CAx-Programmierung – D. Straub

Face – die Fläche

  • Zweidimensional – ein Flächenstück, begrenzt durch Wires
  • Geometrie: eine parametrische Fläche (Ebene, Zylinder, Kugel, Spline, …)
for f in quader.Faces():
    print(f.geomType(), round(f.Area(), 1))     # beim Quader: alle PLANE

Die Namen aus geomType() kehren als Selektoren wieder: %PLANE, %CYLINDER, %CIRCLE.

CAx-Programmierung – D. Straub

Topologie im Viewer

Die Zahlen aus Python lassen sich im Viewer gegenprüfen – Element für Element:

  • Filter in der Werkzeugleiste (oder Tasten v / e / f / s): nur Ecken, Kanten, Flächen oder Körper sind anwählbar
  • Properties: Doppelklick auf ein Element zeigt seinen Typ – bei Flächen z. B. Ebene oder Zylinder mit Mittelpunkt, Radius, Fläche; bei Kanten Gerade oder Kreis mit Länge
  • Esc hebt die Auswahl auf

So sehen Sie, welche Fläche hinter einer Zahl steckt: die vier Zylinderflächen der Verrundung, die Nahtkante am Zylinder.

CAx-Programmierung – D. Straub

Praktikum A: Anatomie der Grundplatte

CAx-Programmierung – D. Straub

Aufgabe 1: Zählen und vorhersagen

Nutzen Sie Ihre Grundplatte aus Einheit 1 (grundplatte, mit vier Bohrungen).

  1. Sagen Sie zuerst voraus: Wie viele Faces, Edges, Vertices hat die Platte mit Bohrungen? Dann zählen – stimmt Ihre Vorhersage?
  2. Was trägt jede Bohrung zur Topologie bei? Was jede Verrundung?
CAx-Programmierung – D. Straub

Aufgabe 2: Geometrietypen

Gehen Sie Flächen und Kanten Ihrer Grundplatte durch.

  1. Welche Geometrietypen kommen bei Flächen vor? Bei Kanten?
  2. Wie viele Kanten sind Kreise? Passt das zur Anzahl der Bohrungen und Verrundungen?
  3. Gegenprobe im Viewer: Wählen Sie mit Properties per Doppelklick eine Bohrungsfläche und eine Verrundung – stimmen Typ und Radius?

Hinweise: .Faces(), .Edges(), .geomType(), .Area(), .Length()

CAx-Programmierung – D. Straub

Aufgabe 3: Wie verändern Features die Topologie?

Sagen Sie vor dem Ausführen voraus, dann prüfen:

  1. Wie ändern sich Faces/Edges/Vertices durch eine zusätzliche Bohrung (- cf.cylinder(...))?
  2. Wie viele Wires hat die Oberseite der Platte? Prüfen Sie mit show_topology(grundplatte): Welcher Wire ist die Außenkontur, welche sind Bohrungen?
CAx-Programmierung – D. Straub

Theorie B: Hierarchie, Orientierung, Selektoren

CAx-Programmierung – D. Straub

Shell – die Hülle

  • Zusammenhängende Menge von Faces, über gemeinsame Edges verbunden
  • Offen oder geschlossen
shell = quader.Shells()[0]
print(len(shell.Faces()), "Flächen in der Shell")   # 6

→ Eine geschlossene Shell begrenzt ein Volumen

CAx-Programmierung – D. Straub

Solid – der Körper

  • Dreidimensional – ein Volumenkörper, begrenzt durch eine oder mehrere Shells
  • Das Zielobjekt der parametrischen Konstruktion
solid = quader.Solids()[0]
print(solid.Volume(), solid.Area())   # Volumen mm³, Oberfläche mm²
CAx-Programmierung – D. Straub

Compound – die Sammlung

  • Container für beliebige Shapes, auch gemischter Typen – ohne nötige Verbindung
gruppe = cf.compound([quader, cf.cylinder(d=10, h=10)])
print(len(gruppe.Solids()), "Solids in der Gruppe")

Selektoren liefern bei mehreren Treffern ein Compound; umgekehrt bündelt cf.compound(liste) eine Python-Liste von Kanten wieder zu einem Argument für cf.fillet oder cf.chamfer.

CAx-Programmierung – D. Straub

Übersicht: Topologie-Hierarchie

Typ Dim. Begrenzt durch Geometrie
Vertex 0D – Punkt
Edge 1D Vertices Kurve
Wire 1D Edges –
Face 2D Wires Fläche
Shell 2D Faces –
Solid 3D Shells –
Compound beliebig – –
CAx-Programmierung – D. Straub

Konnektivität durch gemeinsame Teilelemente

Zwei Flächen sind verbunden, wenn sie eine gemeinsame Kante haben; zwei Kanten, wenn sie einen gemeinsamen Vertex haben. Teilelemente werden geteilt, nicht kopiert.

wuerfel = cf.box(10, 10, 10)
auftritte = sum(len(f.Edges()) for f in wuerfel.Faces())
print(auftritte, "vs.", len(wuerfel.Edges()))   # 24 vs. 12

6 Flächen mit je 4 Kanten ergeben 24 – der Würfel hat aber nur 12 Kanten: Jede Kante gehört zu zwei Flächen.

CAx-Programmierung – D. Straub

Orientierung: warum reicht Topologie allein nicht?

Gedankenexperiment: Sechs quadratische Flächen, zu einer Shell verbunden – ein massiver Würfel, oder eine würfelförmige Aussparung? Die Topologie ist identisch. Fehlende Information: wohin zeigt jede Fläche?

Regel: In einem gültigen Solid zeigt die Normale immer vom Material weg.

for f in grundplatte.Faces()[:3]:
    print(f.normalAt())   # jede Normale zeigt nach außen

→ Wichtig für Boolesche Operationen, Wasserdichtheit, Export (falsche Orientierung → ungültige STL/STEP).

CAx-Programmierung – D. Straub

B-Rep ist Industriestandard

Software Kernel
CATIA CGM
SolidWorks, NX Parasolid
FreeCAD, CadQuery OCCT

Vertex, Edge, Face, Shell, Solid – überall dieselben Konzepte. STEP (ISO 10303) transportiert diese Struktur zwischen Systemen, verlustfrei in der Topologie. Vertiefung: Leseauftrag.

CAx-Programmierung – D. Straub

String-Selektoren

Selektor Bedeutung
>Z / <Z größter / kleinster Z-Wert
>Z[-2] zweithöchste Lage in Z
|Z parallel zur Z-Achse
%CIRCLE / %PLANE / %CYLINDER Geometrietyp

Kombinierbar: grundplatte.edges("<Z and %CIRCLE")

Rückgabe: ein einzelner Treffer ist eine Face/Edge, mehrere Treffer ein Compound. Zum Zählen und Durchlaufen deshalb .Faces() bzw. .Edges() anhängen:

unten = grundplatte.edges("<Z and %CIRCLE").Edges()
print(len(unten))
CAx-Programmierung – D. Straub

Filtern in Python

Was kein String-Selektor trifft, filtern Sie direkt in Python – mit allem, was die Elemente über ihre Geometrie wissen:

groesste = max(grundplatte.Faces(), key=lambda f: f.Area())
zylindrisch = [f for f in grundplatte.Faces() if f.geomType() == "CYLINDER"]
klein = [e for e in unten if e.radius() < 3]     # Kreiskanten nach Radius

Das Ergebnis ist eine Python-Liste; cf.compound(klein) macht daraus wieder ein Argument für cf.fillet/cf.chamfer.

CAx-Programmierung – D. Straub

Warum String vor Index? Ein Vorgriff

⚠️ teil.Faces()[3] meint nicht „diese bestimmte Fläche“, sondern „was gerade an Position 3 steht“. Fügt eine spätere Änderung irgendwo im Modell eine neue Fläche ein, kann Index 3 danach auf eine völlig andere Fläche zeigen – ohne Fehlermeldung.

Das Select-Werkzeug im Viewer zeigt solche Indizes an. Seine Doku warnt selbst: OCCT hält sie nicht einmal zwischen Kernel-Versionen (7.x → 8.x) stabil.

Das heißt Topological Naming Problem; eng verwandt: ob ein Ergebnis überhaupt gültig ist (isValid()). Beides greifen wir später mit einem konkreten Beispiel vollständig auf.

CAx-Programmierung – D. Straub

Praktikum B: Gezielte Selektion und Erweiterung

CAx-Programmierung – D. Straub

Aufgabe 4: Gezielte Selektion

  1. Selektieren Sie die Oberseite der Platte – Typ und Flächeninhalt?
  2. Selektieren Sie alle zylindrischen Flächen – wie viele? Woher kommen sie alle?
  3. Fasen Sie die unteren Kanten der Bohrungen (0,5 mm) über ein Kriterium statt über den Index. Prüfen Sie zuerst, was "<Z and %CIRCLE" alles trifft, und grenzen Sie die Auswahl bei Bedarf in Python ein.

Hinweise: .Faces()/.Edges() zum Zählen, e.radius(), cf.compound(liste), cf.chamfer(teil, kanten, 0.5)

CAx-Programmierung – D. Straub

Aufgabe 5: Zentrierzapfen auf der Oberseite (Vorgriff)

Bauen Sie einen Zentrierzapfen (⌀ 16 mm, Höhe 8 mm) mittig auf die Oberseite der Platte – er positioniert später den Zellstapel. Nutzen Sie zunächst eine fest angenommene Höhe (z = 6).

Denkfrage: Was passiert mit z = 6, wenn die Grundplatte dicker wird? Nächste Woche leiten wir die Platzierung aus der Fläche selbst ab.

CAx-Programmierung – D. Straub

Zusatzaufgabe: Lüftungslochraster

Bauen Sie eine Platte 170 × 110 × 6 mm (Ecken r = 6) mit einem 4 × 3-Raster von Lüftungslöchern (⌀ 8 mm), Rastermaß 36 mm (x) und 32 mm (y).

  1. Wie viele Flächen hat die Platte, wie viele davon zylindrisch? Passt die Zahl zu 12 Löchern?
  2. Verrunden Sie die oberen Kanten der Lüftungslöcher (r = 1 mm).

Hinweise: zwei verschachtelte for-Schleifen, cf.cylinder, .moved(cf.Location(...)), Selektor ">Z and %CIRCLE", Filter über e.radius()

CAx-Programmierung – D. Straub

Zusatzaufgabe: Topologie eines fremden Modells

import cadquery
teil = cadquery.importers.importStep("mein_teil.step").val()

Als Quelle eignet sich jede STEP-Datei, z. B. ein Normteil aus einem Herstellerkatalog oder ein Export aus einem anderen CAD-System.

importStep ist die einzige Stelle im Kurs, an der kurz die Workplane-API auftaucht – .val() holt sofort die normale Shape heraus. Wie viele Faces/Edges/Vertices hat das fremde Teil? Welche Geometrietypen kommen vor?

CAx-Programmierung – D. Straub

Abschluss

CAx-Programmierung – D. Straub

Leseauftrag & Ausblick

  • Leseauftrag: Buch Kapitel 5 (erste Hälfte)
  • Wer mehr will: Prädikat-Selektoren für Fälle, die kein String trifft (Buch Kapitel 5)
  • Nächste Woche: Grundformen – Extrude, Muster; die Pouch-Zelle, der Zellstapel und die Endplatten kommen dazu
  • Bis dahin: w02/ committet und gepusht
CAx-Programmierung – D. Straub